#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <signal.h>

#include "global.h"
#include "constantes.h"
#include "sockets.h"
#include "NIPC.h"
#include "listas.h"
#include "sincronizador2.h"


extern int numeroSincro;
extern int contador;

	
void *syncer(void *args) {
  
	int i,j,ret,flag,salto;
	char buffer[512];
	char buffer_sect[20];
	char buffer_id[20];
	disco* pAux;
	int iSocketDisco_temporal;  
	disco * dsk = (struct DiscoConocido *) args;	
	int owner = numeroSincro;
	numeroSincro++;
	char* vacia=(char *)malloc(512);
	memset(vacia,'\0',512);
	int iSocket_temporal;
	int puerto;
	char* sPuerto=(char*)malloc(20);
	
		
	while(dsk->sectores < 1048576)
	{
		
		disco* discoElegido = (disco*)asignarread((dsk->sectores), owner);
		InfoIPC rInfoIPC;
		recibirIPC(*(discoElegido->iSocketHDAParaArray),&rInfoIPC);			
		discoElegido->pendings--;
		
		if(strchr(rInfoIPC.payload, ';') != NULL)
		{
			/*strcpy(buffer_id, strtok(rInfoIPC.payload, ","));
			strcpy(buffer_sect,strtok(NULL, ";"));
			strcpy(buffer, strtok(NULL, "\r\n\0"));
			*/
			strcpy(buffer, strtok(rInfoIPC.payload, ";"));
			strcpy(buffer_id, strtok(buffer, ","));
			strcpy(buffer_sect, strtok(NULL, "\r\n\0"));
		}
		
		printf("buffer_id %s \n",buffer_id);
		printf("buffer_sect %s \n",buffer_sect);
		printf("buffer %s \n",buffer);
		asignarwrite(dsk,owner,atoi(buffer_sect),buffer);
		InfoIPC rInfoIPC2;
		recibirIPC(*(dsk->iSocketHDAParaArray),&rInfoIPC2);				
		dsk->pendings--;
		dsk->sectores++;
		
		printf("Se sincronizaron los primeros %i sectores\n",dsk->sectores);
	}
	
	printf("Se finalizo la sincronizacion del disco %s\n", dsk->sNombre);
	dsk->Estado = LISTO;
	printf("DISCO LISTO\n");

}


disco* asignarread(int sector, int owner) {
    
	char * sContador=(char*)malloc(20);
	int payload;
	char *sAux=(char *)malloc(20);
	int ret;
	int tamanio_buff ;
	char *buffer;
	
	disco *dsk = (disco *)elegirDisco(sector);
	
	
	if(pthread_mutex_lock(&(mutex3))!=0){
		perror("pthread_mutex_lock");
		exit(EXIT_FAILURE);
	}
			
	contador++;			
			
	if(pthread_mutex_unlock(&(mutex3))!=0){
		perror("pthread_mutex_lock");
		exit(EXIT_FAILURE);
	}
	
	
	intacad(contador,sContador);

	memset(sAux,'\0',20);
	intacad(sector,sAux);	
	
	payload=READ_SECTORSYNC_REQUEST;
	
	tamanio_buff = strlen(sContador) + 1 + strlen(sAux) + 2 ;
	buffer = (char *) malloc (sizeof(char) * tamanio_buff);

	strcpy(buffer,sContador);
	strcat(buffer, ",");
	strcat(buffer, sAux);
	strcat(buffer, ";");
			
	InfoIPC rInfoIPC3;
	rInfoIPC3.payLoadLength=tamanio_buff;
	generarStructIPC(buffer,payload,&rInfoIPC3);
	printf("Antes de enviar a disco\n ");
	enviarIPC(dsk->iSocketHDAParaDA,&rInfoIPC3);	
	free(rInfoIPC3.payload);
	
	dsk->pendings++;
	
	free(buffer);
	free(sAux);
	free(sContador);
	
	return dsk;

}

void asignarwrite(struct DiscoConocido *dsk, int owner,int sector,char *data) {
	
	char * sContador=(char*)malloc(20);
	int payload;
	char *sAux=(char *)malloc(20);
	int ret; 
	int tamanio_buff ;
	char *buffer; 
	 
	

	if(pthread_mutex_lock(&(mutex3))!=0){
		perror("pthread_mutex_lock");
		exit(EXIT_FAILURE);
	}
	
	contador++;			
		
	if(pthread_mutex_unlock(&(mutex3))!=0){
		perror("pthread_mutex_lock");
		exit(EXIT_FAILURE);
	}
	
	intacad(contador,sContador);
	dsk->pendings++;
	memset(sAux,'\0',20);
	intacad(sector,sAux);	
	payload=WRITE_SECTORSYNC_REQUEST;
	tamanio_buff = strlen(sContador) + 1 + strlen(sAux) + 1 + 512 + 1;
	buffer = (char *) malloc (sizeof(char) * tamanio_buff);
	strcpy(buffer,sContador);
	strcat(buffer, ",");
	strcat(buffer, sAux);
	strcat(buffer, ";");
	memcpy(buffer + strlen(sContador) + 1 + strlen(sAux)+1,data,512);
	InfoIPC rInfoIPC3;
	rInfoIPC3.payLoadLength=tamanio_buff;
	generarStructIPC(buffer,payload,&rInfoIPC3);
	enviarIPC(dsk->iSocketHDAParaDA,&rInfoIPC3);	
	free(rInfoIPC3.payload);
	
	dsk->pendings++;
	
	free(buffer);
	free(sAux);
	free(sContador);
	
}
